const crypto = require('crypto');

class CaptchaService {
  constructor() {
    if (!CaptchaService.store) {
      CaptchaService.store = new Map();
    }
    this.ttlMs = 2 * 60 * 1000; // 2分钟有效期
  }

  generateCaptcha() {
    const text = this._randomText(5);
    const id = this._generateId();
    const expiresAt = Date.now() + this.ttlMs;
    const svg = this._generateSvg(text);
    const image = 'data:image/svg+xml;base64,' + Buffer.from(svg).toString('base64');

    CaptchaService.store.set(id, { text, expiresAt });

    // 返回图形验证码（为便于测试，返回text；生产环境应移除text）
    return {
      id,
      image,
      expires_in: Math.floor(this.ttlMs / 1000),
      text
    };
  }

  verifyCaptcha(id, input) {
    const record = CaptchaService.store.get(id);
    if (!record) return false;
    const { text, expiresAt } = record;
    // 过期
    if (Date.now() > expiresAt) {
      CaptchaService.store.delete(id);
      return false;
    }
    // 验证（不区分大小写）
    const ok = (String(input || '')).trim().toLowerCase() === String(text).toLowerCase();
    // 验证后即销毁，防止重复使用
    CaptchaService.store.delete(id);
    return ok;
  }

  _randomText(len) {
    const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
    let out = '';
    for (let i = 0; i < len; i++) {
      out += chars[Math.floor(Math.random() * chars.length)];
    }
    return out;
  }

  _generateId() {
    return crypto.randomBytes(8).toString('hex');
  }

  _generateSvg(text) {
    const width = 140;
    const height = 48;
    const bgColor = '#f7f7f7';
    const noiseCount = 12;
    const chars = text.split('');

    const noise = Array.from({ length: noiseCount }).map(() => {
      const x1 = Math.random() * width;
      const y1 = Math.random() * height;
      const x2 = Math.random() * width;
      const y2 = Math.random() * height;
      const color = `rgba(${Math.floor(Math.random()*255)},${Math.floor(Math.random()*255)},${Math.floor(Math.random()*255)},0.4)`;
      return `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${color}" stroke-width="1" />`;
    }).join('');

    const fontSize = 28;
    const startX = 18;
    const gap = 24;
    const baseline = 34;

    const letters = chars.map((c, i) => {
      const rotate = (Math.random() * 30 - 15).toFixed(2);
      const x = startX + i * gap + (Math.random() * 6 - 3);
      const y = baseline + (Math.random() * 6 - 3);
      const fill = `rgb(${Math.floor(Math.random()*180)},${Math.floor(Math.random()*180)},${Math.floor(Math.random()*180)})`;
      return `<text x="${x}" y="${y}" font-size="${fontSize}" font-family="Arial, sans-serif" fill="${fill}" transform="rotate(${rotate}, ${x}, ${y})">${c}</text>`;
    }).join('');

    return `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
  <rect width="100%" height="100%" fill="${bgColor}" />
  ${noise}
  ${letters}
</svg>`;
  }
}

module.exports = CaptchaService;